package com.dxp.operation.exception.handler;

import com.dxp.operation.exception.BusinessException;
import com.dxp.operation.exception.ErrEnum;
import com.dxp.operation.vo.respose.base.ErrorResult;
import com.dxp.operation.vo.respose.base.Result;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@RestControllerAdvice
@Component
public class TmxControllerAdvice {

    private final Logger logger = LoggerFactory.getLogger(TmxControllerAdvice.class);

    @ExceptionHandler(BusinessException.class)
    @ResponseStatus(HttpStatus.OK)
    public Result<Object> handlerBusinessException(BusinessException e) {
        return ErrorResult.of(e.getErrEnum(), e.getData().toString());
    }

    @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseStatus(HttpStatus.OK)
    public Result<Object> handlerThrowable(MethodArgumentNotValidException t) {
        BindingResult result = t.getBindingResult();
        List<ObjectError> errors = result.getAllErrors();
        Set<String> errs = errors
                .stream()
                .map(e -> {
                    if (e instanceof FieldError) {
                        FieldError f = (FieldError) e;
                        return String.format("<%s>, %s", f.getField(), f.getDefaultMessage());
                    } else {
                        return e.getDefaultMessage();
                    }
                })
                .collect(Collectors.toSet());
        return ErrorResult.of(ErrEnum  .PARAM_ERR, errs);
    }

    @ExceptionHandler(MissingServletRequestParameterException.class)
    @ResponseStatus(HttpStatus.OK)
    public Result<Object> handlerThrowable(MissingServletRequestParameterException m) {
        return ErrorResult.of(ErrEnum.MISS_PARAMETER_ERR, m.getParameterName());
    }

    @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
    @ResponseStatus(HttpStatus.OK)
    public Result<Object> handlerThrowable(HttpRequestMethodNotSupportedException h) {
        return ErrorResult.of(ErrEnum.HTTP_METHOD_ERR, h.getMethod());
    }

    @ExceptionHandler(Throwable.class)
    @ResponseStatus(HttpStatus.OK)
    public Result<Object> handlerThrowable(Throwable t) {
        logger.error("serer err", t);
        return ErrorResult.of(ErrEnum.SERVER_ERR, t.getMessage());
    }

}
